/*
 * Copyright 2007 Matt Jensen
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */
package org.jtell.internal;

import java.util.Collection;
import java.util.Map;

/**
 * <p>
 * <code>CollectionUtils</code> provides utility methods for dealing with collections and the elements that they
 * contain.
 * </p>
 */
public class CollectionUtils
{
    /**
     * <p>
     * Construct a {@link CollectionUtils} instance.
     * </p>
     */
    private CollectionUtils()
    {
        super();
    }

    /**
     * <p>
     * Determine whether a collection is empty or <code>null</code>.
     * </p>
     *
     * @param collection the collection to check.
     * @return <code>boolean</code> <code>true</code> if the collection is empty or <code>null</code>.
     */
    public static boolean isEmpty(final Collection<?> collection)
    {
        return null == collection || collection.isEmpty();
    }

    /**
     * <p>
     * Determine whether a map is empty or <code>null</code>.
     * </p>
     *
     * @param map the map to check.
     * @return <code>boolean</code> <code>true</code> if the collection is empty or <code>null</code>.
     */
    public static boolean isEmpty(final Map<?, ?> map)
    {
        return null == map || map.isEmpty();
    }

    /**
     * <p>
     * Place the union of two collections into a third collection.
     * </p>
     *
     * @param output the collection to which the items in the union are to be added.
     * @param input1 the first input collection.
     * @param input2 the second input collection.
     */
    public static <T> void addIntersection(final Collection<? super T> output,
                                           final Collection<? extends T> input1,
                                           final Collection<? extends T> input2)
    {
        Guard.notNull("output", output);
        Guard.notNull("input1", input1);
        Guard.notNull("input2", input2);

        // As a small optimization, we will iterate over the smaller of the two collections, checking against the
        // larger.
        final Collection<? extends T> checkCollection;
        final Collection<? extends T> loopCollection;
        if (input1.size() > input2.size())
        {
            checkCollection = input1;
            loopCollection = input2;
        }
        else
        {
            checkCollection = input2;
            loopCollection = input1;
        }
        for (final T element : loopCollection)
        {
            if (checkCollection.contains(element))
            {
                output.add(element);
            }
        }
    }
}
